package com.dy.mongo.controller;

import com.dy.mongo.dto.*;
import com.dy.mongo.dto.RelationCreateDto;
import com.dy.mongo.entity.Person;
import com.dy.mongo.repository.PersonRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/api/graph")
@RequiredArgsConstructor
public class GraphDataController {

    private final PersonRepository personRepo;

    /**
     * 返回所有节点与边，供前端 vis-network 一次性渲染。
     */
    @GetMapping("/all")
    public GraphDataDto getAll() {
        List<Person> persons = personRepo.findAll();
        List<GraphNode> nodes = persons.stream()
                .map(p -> new GraphNode(p.getCsvId(), p.getName(), p.getAlias(), p.getSpecies()))
                .toList();

        List<GraphEdge> edges = new ArrayList<>();
        for (Person p : persons) {
            Long fromId = p.getCsvId();
            p.getRelations().forEach((type, list) -> {
                for (Person target : list) {
                    if (target.getCsvId() == null) continue;
                    edges.add(new GraphEdge(fromId, target.getCsvId(), type));
                }
            });
        }
        return new GraphDataDto(nodes, edges);
    }

    /**
     * 新增一条关系：fromId -> toId (type)
     */
    @PostMapping("/relation")
    public ResponseEntity<?> createRelation(@RequestBody RelationCreateDto dto) {
        Person from = personRepo.findByCsvId(dto.fromId());
        Person to = personRepo.findByCsvId(dto.toId());
        if (from == null || to == null) {
            return ResponseEntity.badRequest().body("fromId 或 toId 对应的人物不存在");
        }
        from.addRelation(dto.type(), to);
        personRepo.save(from);
        return ResponseEntity.ok("关系已创建");
    }

    /**
     * 创建新人物节点
     */
    @PostMapping("/person")
    public ResponseEntity<?> createPerson(@RequestBody PersonCreateDto dto) {
        if (dto.csvId() == null || dto.name() == null || dto.name().isBlank()) {
            return ResponseEntity.badRequest().body("csvId 与 name 必填");
        }
        if (personRepo.findByCsvId(dto.csvId()) != null) {
            return ResponseEntity.status(HttpStatus.CONFLICT).body("csvId 已存在");
        }
        Person p = new Person();
        p.setCsvId(dto.csvId());
        p.setName(dto.name());
        p.setAlias(dto.alias());
        p.setSpecies(dto.species());
        personRepo.save(p);
        return ResponseEntity.ok("节点已创建");
    }

    /**
     * 删除节点，前提是无任何关联关系
     */
    @DeleteMapping("/person/{csvId}")
    public ResponseEntity<?> deletePerson(@PathVariable Long csvId) {
        Person target = personRepo.findByCsvId(csvId);
        if (target == null) return ResponseEntity.notFound().build();

        // 1. 检查自身是否有子关系
        if (!target.getRelations().isEmpty()) {
            return ResponseEntity.status(HttpStatus.CONFLICT).body("节点仍有子关系，无法删除");
        }

        // 直接删除节点（即使被其他节点引用）。
        personRepo.delete(target);
        return ResponseEntity.ok("已删除");
    }
} 